﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.Diagnostics;
using OAuth.Net.Common;

namespace NFAPI
{
    public partial class QueueView : Form
    {
        public enum QueueType { Disc, InstantWatch }

        #region Private Properties
        private NetflixService service = new NetflixService();

        public delegate Queue GetDelegate(INetflixService service, int startPosition);
        public delegate QueueUpdateStatus UpdateDelegate(INetflixService service, QueueItem item, Queue queue);

        private Dictionary<QueueType, GetDelegate> Get = new Dictionary<QueueType, GetDelegate>
        {
            { QueueType.Disc, new GetDelegate(QueueDal.GetDiscQueue) },
            { QueueType.InstantWatch, new GetDelegate(QueueDal.GetInstantWatchQueue) }
        };

        private Dictionary<QueueType, UpdateDelegate> Update = new Dictionary<QueueType, UpdateDelegate>
        {
            { QueueType.Disc, new UpdateDelegate(QueueDal.UpdateDiscQueue) },
            { QueueType.InstantWatch, new UpdateDelegate(QueueDal.UpdateInstantWatchQueue) }
        };

        private Queue q;
        public QueueType Type { get; set; }

        public bool AllowUpdates { get; set; }
        #endregion

        public QueueView(bool allowUpdates, QueueType queueType)
        {
            AllowUpdates = allowUpdates;
            InitializeComponent();
            dataGridView1.AllowUserToDeleteRows = allowUpdates;
            Position.ReadOnly = !allowUpdates;
            Type = queueType;
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            button2.Visible = false;
            try
            {
                q = Get[Type](service, 0);
                if (q.NumberOfResults <= q.ResultsPerPage) button1.Visible = false;
                queueItemBindingSource.DataSource = q.Items;
            }
            catch (OAuthNotAuthorizedException)
            {
                Process.Start(@"C:\Program Files\Opera\opera.exe", service.AuthenticationUri.AbsoluteUri);
                button3.Visible = true;
            }

            dataGridView1.UserAddedRow += new DataGridViewRowEventHandler(dataGridView1_UserAddedRow);
            dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
        }

        void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            QueueItem item = dataGridView1.SelectedCells[0].OwningRow.DataBoundItem as QueueItem;
            QueueUpdateStatus result = Update[Type](service, item, q);
            if (result.StatusCode == 201)
            {
                q = Get[Type](service, q.StartIndex);
                queueItemBindingSource.DataSource = q.Items;
                dataGridView1.Refresh();
            }
            else
            {
                if (result.FailedEntries.Count > 0)
                    MessageBox.Show("Error: Item position could not be updated.");
                else
                    MessageBox.Show(string.Format("Error: {0}", result.Message));
            }
        }

        void dataGridView1_UserAddedRow(object sender, DataGridViewRowEventArgs e)
        {
            throw new NotImplementedException();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            q = Get[Type](service, q.StartIndex + q.ResultsPerPage);
            button2.Visible = true;
            if (q.NumberOfResults <= q.StartIndex + q.ResultsPerPage) button1.Visible = false;
            queueItemBindingSource.DataSource = q.Items;
            dataGridView1.Refresh();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            q = Get[Type](service, q.StartIndex - q.ResultsPerPage > 0 ? q.StartIndex - q.ResultsPerPage : 0);
            button1.Visible = true;
            if (q.StartIndex > 0) button2.Visible = true;
            queueItemBindingSource.DataSource = q.Items;
            dataGridView1.Refresh();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            q = Get[Type](service, 0);
            if (q.NumberOfResults <= q.ResultsPerPage) button1.Visible = false;
            queueItemBindingSource.DataSource = q.Items;
        }

        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Dispose();
        }

        private void discQueueToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Type == QueueType.Disc) return;

            Type = QueueType.Disc;

            button2.Visible = false;
            q = Get[Type](service, 0);
            if (q.NumberOfResults <= q.ResultsPerPage) button1.Visible = false;
            queueItemBindingSource.DataSource = q.Items;
        }

        private void instantWatchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Type == QueueType.InstantWatch) return;

            Type = QueueType.InstantWatch;

            button2.Visible = false;
            q = Get[Type](service, 0);
            if (q.NumberOfResults <= q.ResultsPerPage) button1.Visible = false;
            queueItemBindingSource.DataSource = q.Items;
        }

        private void dataGridView1_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            QueueItem item = e.Row.DataBoundItem as QueueItem;
            if (QueueDal.DeleteQueueEntry(service, item).StatusCode == 200)
            {
                e.Cancel = false;

                q = Get[Type](service, q.StartIndex);
                queueItemBindingSource.DataSource = q.Items;
                dataGridView1.Refresh();
            }
            else
            {
                e.Cancel = true;
            }
        }
    }
}
